package com.ruoyi.hr.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.hr.common.constant.ResumePageConst;
import com.ruoyi.hr.common.constant.StatusConst;
import com.ruoyi.hr.common.utils.BaseThreadLocal;
import com.ruoyi.hr.common.utils.EmailSender;
import com.ruoyi.hr.common.utils.StatusParser;
import com.ruoyi.hr.domain.HrCheck;
import com.ruoyi.hr.domain.dto.HrLogAddDto;
import com.ruoyi.hr.domain.vo.HrCheckVo;
import com.ruoyi.hr.domain.vo.HrResumeAddVo;
import com.ruoyi.hr.domain.vo.HrResumeQueryVo;
import com.ruoyi.hr.service.IHrOperateLogService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.hr.mapper.HrResumeMapper;
import com.ruoyi.hr.domain.HrResume;
import com.ruoyi.hr.service.IHrResumeService;
import org.springframework.transaction.annotation.Transactional;

/**
 * HR简历Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-07-05
 */
@Service
public class HrResumeServiceImpl implements IHrResumeService 
{
    @Autowired
    private HrResumeMapper hrResumeMapper;

    @Autowired
    private HrCheckServiceImpl hrCheckService;

    @Autowired
    private IHrOperateLogService hrOperateLogService;

    @Autowired
    private EmailSender emailSender;

    /**
     * 查询HR简历
     * 
     * @param id HR简历主键
     * @return HR简历
     */
    @Override
    public HrResume selectHrResumeById(Long id)
    {
        return hrResumeMapper.selectHrResumeById(id);
    }

    /**
     * 查询HR简历列表
     * 
     * @param hrResume HR简历
     * @return HR简历
     */
    @Override
    public List<HrResume> selectHrResumeList(HrResume hrResume)
    {
        return hrResumeMapper.selectHrResumeList(hrResume);
    }

    /**
     * 新增HR简历
     * 
     * @return 结果
     */
    @Override
    @Transactional
    public int insertHrResume(HrResumeAddVo hrResumevo)
    {
        // 先插入简历
        HrResume hrResume = new HrResume();
        BeanUtils.copyProperties(hrResumevo,hrResume);
        hrResume.setStatus("0,1,0");
        hrResume.setCreateTime(DateUtils.getNowDate());
        hrResumeMapper.insertHrResume(hrResume);
        // 日志数据准备
        HrLogAddDto hrLog = BaseThreadLocal.getHrLog();
        List<Long> list = new ArrayList<>();
        list.add(hrResume.getId());
        hrLog.setResumeIds(list);


        List<Long> rUserIds = hrResumevo.getRUserIds();
        // 再插入到哪个审核表中
        List<HrCheck> collect = rUserIds.stream().map(item -> {
            HrCheck hrCheck = new HrCheck();
            hrCheck.setIsCheck(StatusConst.Check.CheckStatus.NOCHECK.getCode());
            hrCheck.setResumeId(hrResume.getId());
            hrCheck.setType(StatusConst.Check.TypeStatus.Resume.getCode());
            hrCheck.setUid(item);
            hrCheck.setCreateTime(new Date());
            hrCheck.setUpdateTime(new Date());
            return hrCheck;
        }).collect(Collectors.toList());
        hrCheckService.insertBatch(collect);
        return 1;
    }

    /**
     * 修改HR简历
     * 
     * @param hrResume HR简历
     * @return 结果
     */
    @Override
    public int updateHrResume(HrResume hrResume)
    {
        hrResume.setUpdateTime(DateUtils.getNowDate());
        return hrResumeMapper.updateHrResume(hrResume);
    }

    /**
     * 批量删除HR简历
     * 
     * @param ids 需要删除的HR简历主键
     * @return 结果
     */
    @Override
    public int deleteHrResumeByIds(Long[] ids)
    {
        return hrResumeMapper.deleteHrResumeByIds(ids);
    }

    /**
     * 删除HR简历信息
     * 
     * @param id HR简历主键
     * @return 结果
     */
    @Override
    public int deleteHrResumeById(Long id)
    {
        return hrResumeMapper.deleteHrResumeById(id);
    }


    /**
     * 按照类型, 得到不同的数据
     * @param hrResume
     * @return
     */
    @Override
    public List<HrResume> selectHrResumeListByType(HrResumeQueryVo hrResume) {
        List<HrResume> list;
        List<String> status = new ArrayList<>();
        Integer queryType = hrResume.getQueryType();
        if (queryType == ResumePageConst.Type.ZERO.getCode()){
            status.add("0,");
        } else if (queryType == ResumePageConst.Type.ONE.getCode()) {
            status.add("0,1,");
            status.add("0,3,");
        } else if (queryType == ResumePageConst.Type.TOW.getCode()) {
            status.add("0,2,");
        } else if (queryType == ResumePageConst.Type.THREE.getCode()) {
            status.add("0,4,");
            status.add("0,5,");
        } else if (queryType == ResumePageConst.Type.FOUR.getCode()) {
            status.add("1,");
        } else if (queryType == ResumePageConst.Type.FIVE.getCode()) {
            status.add("2,");
        } else if (queryType == ResumePageConst.Type.SIX.getCode()) {
            status.add("3,");
        }
        hrResume.setStatusPattern(status);
        list = hrResumeMapper.selectHrResumeListByType(hrResume);
        return list;
    }

    /**
     * 修改简历位置状态
     * @param ids
     * @param code 修改为这个code 指定的状态的
     * @return
     */
	@Override
	public int updatePositionBatch(Long[] ids, int code) {
        // 先批量查询出所有对应的简历嘛
        List<HrResume> list = hrResumeMapper.selectHrResumeByIds(ids);
        StatusParser parseUtil = new StatusParser(list.get(0).getStatus());
        parseUtil.setPositionStatus(code);
        String strStatus = parseUtil.getStrStatus();
        return hrResumeMapper.updateHrResumeByIds(ids, strStatus);
	}

	@Override
    @Transactional
	public void updateHrCheckBatch(HrCheckVo hrCheckVo) {
        List<Long> resumeIds = hrCheckVo.getResumeIds();
        Integer status = hrCheckVo.getStatus();
        Integer checkType = hrCheckVo.getCheckType();
        // 审核表中, 审核状态修改
        hrCheckService.updateHrCheckBatch(resumeIds,status,checkType);
        // 简历审核状态修改,先修改审核状态表,然后如果当前的简历审核状态都通过了, 进入下一个状态, 再是录用审核都通过了, 再进入下一个状态
        //      实时查询当前简历的审核状态, 并按照规定来修改这个状态呗
        List<HrCheck> checks = hrCheckService.selectHrCheckByResumeIds(resumeIds);
        Map<Long, List<HrCheck>> checkMap = checks.stream().collect(Collectors.groupingBy(HrCheck::getResumeId));
        checkMap.entrySet().forEach(item->{
            // 当前简历id
            Long resumeId = item.getKey();
            // 当前简历对应的检查状态数据
            List<HrCheck> resumeChecks = item.getValue();
            boolean check1 = true; // 为true 表示是否开始审核了
            boolean check2 = true;
            for (HrCheck check : resumeChecks) {
                // 只要发现有一个人没有进行审核的, 就不能进行状态的修改
                // 同样的, 只要发下有一个人是不通过的, 修改状态为驳回
                // 之后都是通过的才能修改状态为下一个正常的状态
                if (check.getType() == StatusConst.Check.TypeStatus.Resume.getCode()){
                    // 简历审核的
                    if(check.getIsCheck() == StatusConst.Check.CheckStatus.NOCHECK.getCode()){
                        // 尚未开始审核
                        check1 = false;
                    } else if (check.getIsCheck() == StatusConst.Check.CheckStatus.UNPASS.getCode()) {
                        // 审核不通过
                        check1 = false;
                    }else {
                        // 审核通过
                    }
                }else{
                    // 录用审核的
                    if(check.getIsCheck() == StatusConst.Check.CheckStatus.NOCHECK.getCode()){
                        // 尚未开始审核
                        check2 = false;
                    } else if (check.getIsCheck() == StatusConst.Check.CheckStatus.UNPASS.getCode()) {
                        // 审核不通过
                        check2 = false;
                    }else {
                        // 审核通过
                    }
                }
            }
            // 得到当前的简历
            HrResume hrResume = hrResumeMapper.selectHrResumeById(resumeId);
            StatusParser statusParser = new StatusParser(hrResume.getStatus());
            // 修改当前简历
            // TODO 判断那四个状态字段来决定如何修改状态
            // 查看这个checkMap, 如果这个type==1的所有的都审核通过了,而且原简历是待审核状态, 则原简历进入待面试状态
            // 查看这个checkMap, 如果这个type==2的所有的都审核通过了,而且原简历是待录用状态, 则原简历进入已录用状态
            // 如果通过了, 修改状态为下一个状态(原状态+1)
            if(check1 || check2){
                statusParser.setResumeStatus(statusParser.getResumeStatusCode() + 1);
            }
            // 否则, 原来什么状态就是什么状态, 只是在审核表中体现出来的
            HrResume resume = new HrResume();
            resume.setId(hrResume.getId());
            resume.setStatus(statusParser.getStrStatus());
            resume.setUpdateTime(new Date());
            hrResumeMapper.updateHrResume(resume);
            // TODO 操作日志修改, 就是记录当前简历的一些操作内容什么的
        });
	}

    @Override
    @Transactional
    public void updateHrResumeWithCheck(HrResumeAddVo hrResume) {
        List<Long> rUserIds = hrResume.getRUserIds();
        Long resumeId = hrResume.getId();
        List<HrCheck> hrChecks = rUserIds.stream().map(item -> {
            HrCheck hrCheck = new HrCheck();
            hrCheck.setResumeId(resumeId);
            hrCheck.setType(StatusConst.Check.TypeStatus.Resume.getCode());
            hrCheck.setIsCheck(StatusConst.Check.CheckStatus.NOCHECK.getCode());
            hrCheck.setUid(item);
            hrCheck.setUpdateTime(new Date());
            hrCheck.setCreateTime(new Date());
            return hrCheck;
        }).collect(Collectors.toList());
        // 先删除后插入, TODO 可能要考虑到那些审核过的是否该删
        hrCheckService.deleteHrCheckBatch(resumeId,StatusConst.Check.TypeStatus.Resume.getCode());
        hrCheckService.insertBatch(hrChecks);
        hrResumeMapper.updateHrResume(hrResume);
    }

	@Override
	public List<HrResume> selectByIds(List<Long> resumeIds) {
        Long[] array = resumeIds.stream().toArray(Long[]::new);
        return hrResumeMapper.selectHrResumeByIds(array);
	}

	@Override
	public void updateStatusBatch(List<HrResume> collect) {
        for (HrResume hrResume : collect) {
            hrResumeMapper.updateHrResume(hrResume);
        }
	}

	@Override
	public void doInduction(Long[] ids,int type) {
        Integer induction = null;
		if (type == 1){
            // 入职
            induction = StatusConst.Resume.ResumeStatus.INDUCTION.getCode();
        }else{
            // 取消入职
            induction = StatusConst.Resume.ResumeStatus.HIRE_OK.getCode();
        }
        List<HrResume> hrResumes = hrResumeMapper.selectHrResumeByIds(ids);
        Integer finalInduction = induction;
        hrResumes.forEach(item -> {
            HrResume hrResume = new HrResume();
            hrResume.setUpdateTime(new Date());
            hrResume.setId(item.getId());
            StatusParser statusParser = new StatusParser(item.getStatus());
            statusParser.setResumeStatus(finalInduction);
            hrResume.setStatus(statusParser.getStrStatus());
            hrResumeMapper.updateHrResume(hrResume);
        });
    }

	@Override
	public void sendOffer(Long[] ids) {
        // 依次向这些用户发送offer, offer的模板
        List<HrResume> hrResumes = hrResumeMapper.selectHrResumeByIds(ids);
        hrResumes.forEach(item->{
            emailSender.sendTxt(item);
        });
    }
}
